package com.manlitech.manlichat.base.netty.handler;

import com.alibaba.fastjson.JSONObject;
import com.manlitech.manlichat.base.netty.pool.MyChannelHandlerPool;
import com.manlitech.manlichat.base.netty.util.HttpParseUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * netty http 请求处理 不做长轮训
 * @author Shensg
 */

@Component
@ChannelHandler.Sharable
@Slf4j
public class MyHttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    /**
     * 读取完毕如果关闭则心跳机制无效,因为通道已经关闭
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        log.info("channelReadComplete");
        ctx.flush();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
        log.info("channelRead0");
        //100 Continue
        if (HttpUtil.is100ContinueExpected(req)) {
            ctx.write(new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.CONTINUE));
        }
        // 获取请求的uri

        Map<String,Object> resMap = HttpParseUtil.parse(req);
        log.info("请求参数:{}",resMap);

        JSONObject object = new JSONObject();
        object.put("a",1);
        object.put("b","中国");
        String msg = object.toJSONString();

        // 创建http响应
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));

        // 设置头信息
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
        // write到客户端
        // http 长连接说的是 Tcp 长连接 , http 长轮训指的场景是服务端检测到数据变换然后告诉客户端
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        //用于触发用户事件，包含触发读空闲、写空闲、读写空闲
        if(evt instanceof IdleStateEvent){
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state()== IdleState.READER_IDLE){
                log.info(ctx.channel().id().asShortText()+" 读空闲... ");
            }else if (event.state()==IdleState.WRITER_IDLE){
                log.info(ctx.channel().id().asShortText()+" 写空闲... ");
            }else if (event.state()==IdleState.ALL_IDLE){
                log.info("channel 读写空闲, 准备关闭当前channel  , 当前UsersChanel的数量: "+ MyChannelHandlerPool.channelGroup.size());
                Channel channel = ctx.channel();
                channel.close();
                log.info("channel 关闭后, UsersChanel的数量: "+MyChannelHandlerPool.channelGroup.size());
            }
        }
    }


}